<?php

/**
 * ShelterController
 *
 * @author nagata
 * @version
 */

require_once 'Zend/Controller/Action.php';
require_once 'Zend/Exception.php';

require_once 'Okute/Exception.php';
require_once 'Okute/Util/Data.php';

require_once APPLICATION_PATH . '/models/ShelterModel.php';
require_once APPLICATION_PATH . '/models/AclModel.php';

class ShelterController extends Zend_Controller_Action
{
    /**
     * セッション管理用変数
     * @var Zend_Session_Namespace
     */
    private $_session;

    /**
     * 共通関数用
     * @var Okute_Util_Data
     */
    private $_util;

    /**
     * アクセスコントロール
     * @var Zend_Acl
     */
    private $_acl;

    /**
     * リダイレクトヘルパー
     * @var Okute_Controller_Action_Helper_Redirector
     */
    private $_redirector;

    /**
     * 初期化処理
     *
     * @return void
     */
    public function init()
    {
        $this->_session = new Zend_Session_Namespace('okute');
        $this->_util = new Okute_Util_Data($this->view);
        $this->_acl = Zend_Registry::get('acl');
        $this->_redirector = Zend_Registry::get('redirector');
        $this->view->base = $this->getRequest()->getBaseUrl();
    }

    /**
     * index: なにかする？
     *
     * @return void
     */
    public function indexAction()
    {
    }

    /**
     * 新規登録処理
     *
     * @return void
     */
    public function registAction()
    {
        $this->_session->requester = null;

        $data = null;

        // セッションデータがある場合は「確認画面の戻るボタン」で遷移
        if($this->_session->userData !== null)
        {
            $data = $this->_session->userData;
        }

        // ポストデータがある場合は「入力エラー」により戻された
        if($this->getRequest()->isPost())
        {
            $data = $this->_postToData($this->getRequest(),$data);
        }

        if($data !== null)
        {
            $this->_session->userData = $data;
        }

        $this->view->assign('prefecture',ShelterModel::$prefecture);
        $this->view->data = $data;
    }

    /**
     * 編集処理
     *
     * @return void
     */
    public function editAction()
    {
        $data = null;
        $displayId = null;
        $shelterId = null;

        // セッションデータがない場合は「一覧表示の編集」から遷移
        if($this->_session->userData === null)
        {
            $map = $this->_session->shelterMap;
            if($map === null)
            {
                throw new Okute_Exception('Session data "shelterMap" is required');
            }

            $displayId = $this->getRequest()->getParam('id', null);
            if($displayId === null)
            {
                throw new Okute_Exception('GET parameter "displayId" is requred');
            }
            $this->_session->displayId = $displayId;

            $shelterId = $map[$displayId];
            if($shelterId === null)
            {
                throw new Okute_Exception('No valid "shelter_id" in "shelterMap"');
            }
            $this->_session->shelterId = $shelterId;

            $shelterModel = new ShelterModel();
            $res = $shelterModel->fetchRow(
                $shelterModel->select()->where('shelter_id = ?',$shelterId)
            );
            $data = $res->toArray();
            list($data['lat'],$data['lng']) = explode(',',$data['lat_lng']);
        }
        // セッションデータがある場合は「確認画面の戻るボタン」で遷移
        else
        {
            $data = $this->_session->userData;
        }

        // ポストデータがある場合は「入力エラー」により戻された
        if($this->getRequest()->isPost())
        {
            $data = $this->_postToData($this->getRequest(),$data);
        }

        if($data !== null)
        {
            $this->_session->userData = $data;
        }

        $this->view->assign('prefecture',ShelterModel::$prefecture);
        $this->view->data = $data;
    }

    /**
     * 入力内容確認画面
     *
     * @return void
     */
    public function confirmAction()
    {
        $edit = null;
        $data = null;
        $this->view->errors = null;

        if($this->_session->shelterId === null)
        {
            $edit = false;
            $this->view->back = 'regist';
            $this->view->finish = '登録する';
        }
        else
        {
            $edit = true;
            $this->view->back = 'edit/id/'.$this->_session->displayId;
            $this->view->finish = '変更する';
        }

        $data = $this->_session->userData;
        $data = $this->_postToData($this->getRequest(),$data);

        $errors = $this->_checkInput($data,$edit);
        if(count($errors) > 0)
        {
            $this->view->errors = $errors;
            $this->_forward($this->view->back);
        }

        $this->_session->userData = $data;
        $this->_session->confirm = true;

        $this->view->data = $data;
    }

    /**
     * データベース登録/更新処理
     *
     * @return void
     */
    public function finishAction()
    {
        if ($this->_session->userData === null)
        {
            throw new Okute_Exception('Session data "userData" is required');
        }

        if($this->_session->confirm === null)
        {
            throw new Okute_Exception('Invalid page-transition');
        }
        $this->_session->confirm = null;

        $data = $this->_session->userData;

        $shelterModel = new ShelterModel();

        $db = Zend_Registry::get('database', null);
        if($db === null)
        {
            throw new Okute_Exception('Invalid registry "database"');
        }

        // 新規登録処理
        if($this->_session->requester === null)
        {
            $db->beginTransaction();
            try
            {
                $shelter = $shelterModel->createRow();
                $shelter->prefecture         = $data['prefecture'];
                $shelter->area               = $data['area'];
                $shelter->city               = $data['city'];
                $shelter->district           = $data['district'];
                $shelter->name               = $data['name'];
                $shelter->population         = $data['population'];
                $shelter->capacity           = $data['capacity'];
                $shelter->source             = $data['source'];
                $shelter->source_update_date = $data['source_update_date'];
                $shelter->source_update_time = $data['source_update_time'];
                $shelter->notes              = $data['notes'];
                $shelter->lat_lng            = $data['lat'].','.$data['lng'];
                $shelter->create_datetime    = 'NOW()';
                $shelter->update_datetime    = 'NOW()';
                $shelter->save();

                $db->commit();
                $this->_util->clearSessionData();
            }
            catch (Exception $e)
            {
                $db->rollBack();
                throw $e;
            }
            $this->_redirect('/auth/login');
        }
        // 更新処理
        else
        {
            $shelter_id = $this->_session->shelterId;
            if($shelter_id === null)
            {
                throw new Okute_Exception('Session data "shelterId" is required');
            }

            $db->beginTransaction();
            try
            {
                $shelter = $shelterModel->fetchRow(
                    $shelterModel->select()->where('shelter_id = ?', $shelter_id)
                );
                $shelter->prefecture         = $data['prefecture'];
                $shelter->area               = $data['area'];
                $shelter->city               = $data['city'];
                $shelter->district           = $data['district'];
                $shelter->name               = $data['name'];
                $shelter->population         = $data['population'];
                $shelter->capacity           = $data['capacity'];
                $shelter->source             = $data['source'];
                $shelter->source_update_date = $data['source_update_date'];
                $shelter->source_update_time = $data['source_update_time'];
                $shelter->notes              = $data['notes'];
                $shelter->lat_lng            = $data['lat'].','.$data['lng'];
                $shelter->create_datetime    = 'NOW()';
                $shelter->update_datetime    = 'NOW()';
                $shelter->save();

                $db->commit();
                $this->_util->clearSessionData();
            }
            catch(Exception $e)
            {
                $db->rollBack();
                throw $e;
            }

            $page = $this->_session->page;
            if($page === null)
            {
                $this->_redirector->redirectWithSession($this->view->base.'/shelter/list');
            }
            else
            {
                $this->_redirector->redirectWithSession($this->view->base.'/shelter/list/page/'.$page);
            }
        }
    }

    /**
     * 一覧表示
     *
     * @return void
     */
    public function listAction()
    {
        $this->_config = Zend_Registry::get('config');
        $format = $this->_session->format;
        $count = $this->_config->display->shelter_count_per_page->$format;
        $page = $this->getRequest()->getParam('page',1);

        $this->view->sortkey    = null;
        $this->view->searchPref = null;
        $this->view->setShelter = null;

        // ユーザおよびステータスでフィルタした表示データを取得
        $shelterModel = new ShelterModel();

        $select = $shelterModel->select();
        $select->setIntegrityCheck(false);
        // ポストデータがある場合は検索条件を追加する
        if($this->getRequest()->isPost())
        {
            $sortkey = $this->getRequest()->getParam('sortkey',null);
            if($sortkey != null)
            {
                $sortkey = mb_convert_encoding($sortkey,'utf-8','auto');

                $db = Zend_Registry::get('database', null);
                if($db === null)
                {
                    throw new Okute_Exception('Invalid registry "database"');
                }

                $where = $db->quoteInto("sortkey LIKE ?", '%'.$sortkey.'%');
                $select->where($where);
                $this->view->sortkey = $sortkey;
            }

            $pref = $this->getRequest()->getParam('prefecture',null);
            if($pref != null)
            {
                $pref = mb_convert_encoding($pref,'utf-8','auto');
                $select->where('prefecture = ?',$pref);
                $this->view->searchPref = $pref;
            }
        }
        $select->order('update_datetime');

        try
        {
            Zend_Paginator::setDefaultScrollingStyle('Sliding');
            $shelters = Zend_Paginator::factory($select);
            $shelters->setCurrentPageNumber($page);
            $shelters->setItemCountPerPage($count);
        }
        catch(Exception $exception)
        {
            echo $exception->getMessage();
            return;
        }

        // 不正なページが入力されたときの対策としてpaginatorが保持するページで上書きする
        $page = $shelters->getCurrentPageNumber();

        $map  = array();
        $data = array();
        $offset = $count * ($page-1);
        $displayId = $offset + 1;

        foreach($shelters as $shelter)
        {
            // 表示idとshelter_idのマップを作成
            $map[$displayId] = $shelter->shelter_id;

            // Smartyの表示項目を作成
            $data[$displayId] = array(
                'prefecture'            => $shelter->prefecture,
                'area'                  => $shelter->area,
                'city'                  => $shelter->city,
                'district'              => $shelter->district,
                'name'                  => $shelter->name,
                'population'            => $shelter->population,
                'capacity'              => $shelter->capacity,
                'source'                => $shelter->source,
                'source_update_date'    => $shelter->source_update_date,
                'source_update_time'    => $shelter->source_update_time,
                'notes'                 => $shelter->notes,
                'lat_lng'               => $shelter->lat_lng,
            );
            $displayId++;
        }

        if($this->_session->role == "requester")
        {
            if($this->_session->requester->shelter_id == null)
            {
                $this->view->setShelter = true;
            }
        }

        $this->_session->shelterMap = $map;
        $this->_session->page = $shelters->getPages();

        $this->view->assign('prefecture',ShelterModel::$prefecture);

        $this->view->role   = $this->_session->role;
        $this->view->page   = $shelters->getPages();
        $this->view->offset = $offset;
        $this->view->data = $data;
    }

    private function _postToData($request,$data)
    {
        $columns = array(
            'prefecture',
            'area',
            'city',
            'district',
            'name',
            'population',
            'capacity',
            'source',
            'source_update_date',
            'source_update_time',
            'notes',
            'lat',
            'lng',
        );
        foreach ($columns as $column)
        {
            $val = $request->getPost($column);
            if($val !== null)
            {
                $data[$column] = $this->_util->convertInputEncoding($val);
            }
        }
        return $data;
    }

    /**
     * ユーザ入力のエラーを確認する。エラーが存在した場合には配列にエラーコードとメッセージを含めて返却する。
     * 引数にはRequestModelのデータを入力する。
     *
     * @param Zend_Db_Table_Row $data
     * @return array $errors
     */
    private function _checkInput($data,$edit = false)
    {
        $errors = array();

        // 都道府県     : prefecture
        if(! Zend_Validate::is($data['prefecture'],'NotEmpty'))
        {
            $errors[] = array('code' => '1000', 'message' => '都道府県を選択してください。');
        }

        // 地域         : area

        // 市町村名     : city

        // 地区名       : district

        // 避難場所名称 : name
        if(! Zend_Validate::is($data['name'],'NotEmpty'))
        {
            $errors[] = array('code' => '1000', 'message' => '氏名/ニックネームを入力してください。');
        }

        // 避難人数     : population|escape}人</p>

        // キャパシティ : capacity|escape}人</p>

        // ソース       : source

        // ソース更新日 : source_update_date

        // ソース時間   : source_update_time

        // コメント     : notes

        // 緯度         : lat

        // 経度         : lng

        /*
        if($edit === false)
        {
        }
        */

        return $errors;
    }
}
